/*
 * MIT License
 *
 * Copyright (c) 2023 北京凯特伟业科技有限公司
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */
package com.je.workflow.service.approvalnotice;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.lang.UUID;
import com.google.common.base.Strings;
import com.je.bpm.core.model.BpmnModel;
import com.je.bpm.engine.HistoryService;
import com.je.bpm.engine.RepositoryService;
import com.je.bpm.engine.approvalnotice.ActivitiApprovalNotice;
import com.je.bpm.engine.approvalnotice.TaskApprovalNoticeEnum;
import com.je.bpm.engine.delegate.DelegateExecution;
import com.je.bpm.engine.history.HistoricIdentityLink;
import com.je.bpm.engine.impl.bpmn.behavior.KaiteBaseUserTaskActivityBehavior;
import com.je.bpm.engine.impl.bpmn.behavior.KaiteUserTaskActivityBehavior;
import com.je.bpm.engine.impl.identity.Authentication;
import com.je.common.base.DynaBean;
import com.je.common.base.mapper.query.NativeQuery;
import com.je.common.base.service.CommonService;
import com.je.common.base.service.MetaService;
import com.je.common.base.spring.SpringContextHolder;
import com.je.rbac.rpc.MetaRbacRpcServiceImpl;
import com.je.workflow.service.push.PushService;
import com.je.workflow.service.user.WorkFlowUserService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;

/**
 * 审批告知
 */
@Service
public class ActivitiApprovalNoticeImpl implements ActivitiApprovalNotice {

    private static final Logger logger = LoggerFactory.getLogger(KaiteUserTaskActivityBehavior.class);

    public static final String END_NODE = "结束节点";
    @Autowired
    private MetaService metaService;
    @Autowired
    private CommonService commonService;
    @Autowired
    private PushService pushService;
    @Autowired
    private WorkFlowUserService workFlowUserService;
    @Autowired
    MetaRbacRpcServiceImpl metaRbacRpcService;

    @Override
    public void sendNotice(List<TaskApprovalNoticeEnum> taskApprovalNoticeEnumList, DelegateExecution execution, String assignee, String comment, String submitType, String toAssignee, String modelName, String beanId) {
        //发送
        try {
            sendMessage(execution, taskApprovalNoticeEnumList, assignee, comment, submitType, toAssignee, modelName, beanId);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }


    public void sendMessage(DelegateExecution execution, List<TaskApprovalNoticeEnum> taskApprovalNoticeEnumList, String assignee, String comment, String submitType, String toAssignee, String modelName, String beanId) {
        String pdId = execution.getProcessDefinitionId();
        RepositoryService repositoryService = SpringContextHolder.getBean(RepositoryService.class);
        //获取bpmnModel
        BpmnModel bpmnModel = repositoryService.getBpmnModel(pdId);
        String processInfoKey = repositoryService.createProcessDefinitionQuery().processDefinitionId(pdId).singleResult().getKey();
        //节点Id
        String piId = execution.getProcessInstanceId();
        //功能信息
        String funcCode = bpmnModel.getMainProcess().getProcessConfig().getFuncCode();
        String tableCode = bpmnModel.getMainProcess().getProcessConfig().getTableCode();

        String modelId = bpmnModel.getMainProcess().getId();

        //节点发起人
        List<String> userList = new ArrayList<>();
        String startUser = "";
        HistoryService historyService = SpringContextHolder.getBean(HistoryService.class);
        List<HistoricIdentityLink> historicIdentityLinks = historyService.getHistoricIdentityLinksForProcessInstance(piId);
        if (historicIdentityLinks != null && historicIdentityLinks.size() > 0) {
            for (HistoricIdentityLink historicIdentityLink : historicIdentityLinks) {
                if ("starter".equals(historicIdentityLink.getType())) {
                    startUser = historicIdentityLink.getUserId();
                    userList.add(historicIdentityLink.getUserId());
                }
                if ("participant".equals(historicIdentityLink.getType())) {
                    userList.add(historicIdentityLink.getUserId());
                }
            }
        }
        String assigneeName = "";
        String[] assignees = assignee.split(",");
        for (String str : assignees) {
            if (Strings.isNullOrEmpty(assigneeName)) {
                assigneeName = workFlowUserService.getUserNameById(str);
            } else {
                assigneeName = assigneeName + "," + workFlowUserService.getUserNameById(str);
            }
        }
        String toAssigneeName = "";
        if(END_NODE.equals(toAssignee)){
            toAssigneeName = toAssignee;
        }else {
            String[] toAssignees = toAssignee.split(",");
            for (String str : toAssignees) {
                if (Strings.isNullOrEmpty(toAssigneeName)) {
                    toAssigneeName = workFlowUserService.getUserNameById(str);
                } else {
                    toAssigneeName = toAssigneeName + "," + workFlowUserService.getUserNameById(str);
                }
            }
        }
        //首页展示标题
        String title = String.format("%s在@dateNow@%s了【%s】任务,执行操作:%s,请及时查看！",
                assigneeName, submitType, modelName, submitType);
        title = title.replaceAll("@dateNow@", "%s");
        //首页内容
        String content = "";
        if (Strings.isNullOrEmpty(comment)) {
            content = String.format("%s，由【%s】",
                    DateUtil.now(), assigneeName + submitType + "给" + toAssigneeName);
        } else {
            if (Strings.isNullOrEmpty(toAssigneeName)) {
                content = String.format("%s，由【%s】, 意见：%s",
                        DateUtil.now(), assigneeName + submitType + "给分支聚合节点", comment);
            } else {
                content = String.format("%s，由【%s】, 意见：%s",
                        DateUtil.now(), assigneeName + submitType + "给" + toAssigneeName, comment);
            }
        }
        //推送内容
        String msgContent = String.format("%s，由【%s】的%s任务，请及时查看！",
                DateUtil.now(), assigneeName + submitType + "给" + toAssigneeName, modelName);
        //会签、多人审批、
        Object submitIsGateWay = execution.getTransientVariable(KaiteBaseUserTaskActivityBehavior.SUBMIT_IS_GATEWAY);
        if (null != submitIsGateWay && Boolean.valueOf(submitIsGateWay.toString())) {
            content = String.format("%s，由%s【%s】给分支聚合节点, 意见：%s",
                    DateUtil.now(), assigneeName, submitType, comment);
            msgContent = String.format("%s，由%s【%s】给分支聚合节点%s任务，请及时查看！", DateUtil.now(), assigneeName, submitType, modelName);
        }
        for (TaskApprovalNoticeEnum taskApprovalNoticeEnum : taskApprovalNoticeEnumList) {
            if (taskApprovalNoticeEnum.name().equals(TaskApprovalNoticeEnum.STARTUSER.name())) {
                if (Strings.isNullOrEmpty(startUser)) {
                    continue;
                }
                //获取真实用户ID
                String associationId = workFlowUserService.getAssociationIdById(startUser);
                String userName = workFlowUserService.getUserNameById(startUser);
                //保存
                doSave(modelId, title, content, funcCode, tableCode, beanId, piId, assigneeName, assignee, userName, startUser, processInfoKey);
                //推送
                pushService.pushApprovalNoticeMsg(associationId, funcCode, modelName, title, msgContent, beanId);
                pushService.pushRefresh(associationId);
            } else if (taskApprovalNoticeEnum.name().equals(TaskApprovalNoticeEnum.APPROVEDPERSON.name())) {
                for (String assigneeId : userList) {
//                    if (startUser.equals(assigneeId)) {
//                        continue;
//                    }
                    String associationId = workFlowUserService.getAssociationIdById(assigneeId);
                    String userName = workFlowUserService.getUserNameById(assigneeId);
                    //保存
                    doSave(modelId, title, content, funcCode, tableCode, beanId, piId, assigneeName, assignee, userName, assigneeId, processInfoKey);
                    //推送
                    pushService.pushApprovalNoticeMsg(associationId, funcCode, modelName, title, msgContent, beanId);
                    pushService.pushRefresh(associationId);
                }
            } else if (taskApprovalNoticeEnum.name().equals(TaskApprovalNoticeEnum.APPROVERDIRECTLEADER.name())) {
                //最后节点的操作人
                String associationId = Authentication.getAuthenticatedUser().getRealUser().getId();
                //直属领导ID
                List<DynaBean> dynaBeanList = metaRbacRpcService.selectByNativeQuery(NativeQuery.build().tableCode("JE_RBAC_VDEPTUSER").eq("JE_RBAC_USER_ID", associationId));
                for (DynaBean dynaBean : dynaBeanList) {
                    String directleaderId = dynaBean.getStr("DEPTUSER_DIRECTLEADER_ID");
                    String directleaderName = dynaBean.getStr("DEPTUSER_DIRECTLEADER_NAME");
                    //根据直属领导的真实用户id查账户部门id
                    List<DynaBean> dynaBeans = metaRbacRpcService.selectByNativeQuery(NativeQuery.build().tableCode("JE_RBAC_VUSERQUERY").eq("USER_ID", directleaderId));
                    for (DynaBean bean : dynaBeans) {
                        String accountdeptId = bean.getStr("JE_RBAC_ACCOUNTDEPT_ID");
                        //保存
                        doSave(modelId, title, content, funcCode, tableCode, beanId, piId, assigneeName, assignee, directleaderName, accountdeptId, processInfoKey);
                    }
                    //推送
                    pushService.pushApprovalNoticeMsg(directleaderId, funcCode, modelName, title, msgContent, beanId);
                    pushService.pushRefresh(directleaderId);
                }
            } else if (taskApprovalNoticeEnum.name().equals(TaskApprovalNoticeEnum.APPROVERDEPTLEADER.name())) {
                String associationId = Authentication.getAuthenticatedUser().getRealUser().getId();
                //部门领导
                List<DynaBean> dynaBeanList = metaRbacRpcService.selectByNativeQuery(NativeQuery.build().tableCode("JE_RBAC_VDEPTUSER").eq("JE_RBAC_USER_ID", associationId));
                for (DynaBean dynaBean : dynaBeanList) {
                    String departmentId = dynaBean.getStr("JE_RBAC_DEPARTMENT_ID");
                    DynaBean departmentBean = metaRbacRpcService.selectOne("JE_RBAC_DEPARTMENT", NativeQuery.build().eq("JE_RBAC_DEPARTMENT_ID", departmentId), "DEPARTMENT_MAJOR_ID");
                    String departmentMajorId = departmentBean.getStr("DEPARTMENT_MAJOR_ID");
                    String departmentMajorName = departmentBean.getStr("DEPARTMENT_MAJOR_NAME");
                    //根据部门领导的真实用户id查账户部门id
                    List<DynaBean> dynaBeans = metaRbacRpcService.selectByNativeQuery(NativeQuery.build().tableCode("JE_RBAC_VUSERQUERY").eq("USER_ID", departmentMajorId));
                    for (DynaBean bean : dynaBeans) {
                        String accountdeptId = bean.getStr("JE_RBAC_ACCOUNTDEPT_ID");
                        //保存
                        doSave(modelId, title, content, funcCode, tableCode, beanId, piId, assigneeName, assignee, departmentMajorName, accountdeptId, processInfoKey);
                    }
                    //推送
                    pushService.pushApprovalNoticeMsg(departmentMajorId, funcCode, modelName, title, msgContent, beanId);
                    pushService.pushRefresh(departmentMajorId);
                }
            }
        }
    }

    public void doSave(String modelId, String title, String content, String funcCode, String tableCode, String
            beanId, String piId, String fromUser, String fromUserId, String toUser, String toUserId, String processInfoKey) {
        //保存
        DynaBean noticeDynaBean = new DynaBean("JE_WORKFLOW_APPROVALNOTICE", false);
        noticeDynaBean.setStr("APPROVALNOTICE_PROCESSINFOKEY", processInfoKey);
        noticeDynaBean.setStr("APPROVALNOTICE_TITLE", title);
        noticeDynaBean.setStr("APPROVALNOTICE_CONTENT", content);
        noticeDynaBean.setStr("APPROVALNOTICE_FUNCCODE", funcCode);
        noticeDynaBean.setStr("APPROVALNOTICE_TABLENAME", tableCode);
        noticeDynaBean.setStr("APPROVALNOTICE_PKID", beanId);
        noticeDynaBean.setStr("APPROVALNOTICE_PIID", piId);
        noticeDynaBean.setStr("APPROVALNOTICE_FROMUSER", fromUser);
        noticeDynaBean.setStr("APPROVALNOTICE_FROMUSER_ID", fromUserId);
        noticeDynaBean.setStr("APPROVALNOTICE_TOUSER", toUser);
        noticeDynaBean.setStr("APPROVALNOTICE_TOUSER_ID", toUserId);
        noticeDynaBean.setStr("APPROVALNOTICE_XXZT_CODE", "0");
        noticeDynaBean.setStr("APPROVALNOTICE_XXZT_NAME", "未读");
        noticeDynaBean.setStr("JE_WORKFLOW_APPROVALNOTICE_ID", UUID.randomUUID().toString());
        commonService.buildModelCreateInfo(noticeDynaBean);
        metaService.insert(noticeDynaBean);
    }

}
